package top.codef.sqlfilter;

import java.util.Collection;

import jakarta.persistence.criteria.Expression;
import top.codef.sqlfilter.functional.SelectCondition;

public class HavingCommonFilter extends AbstractFilter<HavingCommonFilter> {

	public <T> HavingCommonFilter eq(SelectCondition select, T value) {
		if (checkNotNull(value)) {
			list.add((query, builder, path) -> {
				return builder.equal(select.select(builder, path), confirmValue(query, builder, value));
			});
		}
		return this;
	}

	public <T> HavingCommonFilter neq(SelectCondition field, T value) {
		if (checkNotNull(value))
			list.add((query, builder, path) -> builder.notEqual(field.select(builder, path),
					confirmValue(query, builder, value)));
		return this;
	}

	public HavingCommonFilter isNull(SelectCondition field) {
		list.add((query, builder, path) -> builder.isNull(field.select(builder, path)));
		return this;
	}

	public <T> HavingCommonFilter isNotNull(SelectCondition field) {
		list.add((query, builder, path) -> builder.isNotNull(field.select(builder, path)));
		return this;
	}

	public <T> HavingCommonFilter in(SelectCondition field, Collection<T> val) {
		list.add((query, builder, path) -> builder.in(field.select(builder, path)).in(val));
		return this;
	}

	public <T> HavingCommonFilter notIn(SelectCondition field, Collection<T> val) {
		list.add((query, builder, path) -> builder.not(builder.in(field.select(builder, path)).in(val)));
		return this;
	}

	@SuppressWarnings("unchecked")
	public HavingCommonFilter like(SelectCondition field, String val) {
		list.add((query, builder, path) -> builder.like((Expression<String>) field.select(builder, path), val));
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T extends Comparable<? super T>> HavingCommonFilter lt(SelectCondition field, T value) {
		if (checkNotNull(value))
			list.add((query, builder, path) -> builder.lessThan((Expression<T>) field.select(builder, path), value));
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T extends Comparable<T>> HavingCommonFilter le(SelectCondition field, T value) {
		if (checkNotNull(value))
			list.add((query, builder, path) -> builder.lessThanOrEqualTo((Expression<T>) field.select(builder, path),
					value));
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T extends Comparable<T>> HavingCommonFilter gt(SelectCondition field, T value) {
		if (checkNotNull(value))
			list.add((query, builder, path) -> builder.greaterThan((Expression<T>) field.select(builder, path), value));
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T extends Comparable<T>> HavingCommonFilter ge(SelectCondition field, T value) {
		if (checkNotNull(value))
			list.add((query, builder, path) -> builder.greaterThanOrEqualTo((Expression<T>) field.select(builder, path),
					value));
		return this;
	}

}
